Hallo, für das Auslesen einer komplexen "Baumstruktur" benötige ich multiple Halte-/Abzweigpunkte auf die ich dann zurückgehe und von dort die weitere Auslese jeweils starten möchte. Diese Abzweigpunkte (x/y) möchte ich auf den Stapel abspeichern, um sie dann später runterzuholen und weiterzuverarbeiten. Gibt es eine Obergrenze für den Stapel? Ich rechne mit maximal 10-20 Abzweigpunkten auf einmal (also dann x2 wegenx und y-Wert). Grüße Peter
PHA - PLA
Nach spätestens 256 Bytes "läuft der Stapel über" und beginnt von vorne. Warum spätestens? Weil Rücksprungadressen mit ihren jeweils 2 Bytes auch auf dem Stapel liegen...
Hallo,
für mal eben was zwischenspeichern ist der Prozessorstapel sicherlich gut geeignet, vor allem weil es schnell ist.
Abgesehen von der Tatsache der beschränkten Größe finde ich aber etwas ganz anderes wichtig:
Wenn da Daten draufgelegt werden darf das nicht mit den Rücksprungadressen des Prozessors durcheinanderkommen.
Bei sowas wie
JSR machwas
...
machwas
LDA #4
PHA
TAX
LDA wert,X
PHA
RTS
landet das Programm ganz bestimmt nicht da wo es hin wollte.
Umgekehrt geht das auch nicht:
loop
LDX #5
LDA meinedaten,X
PHA
DEX
BPL loop
JSR fillplayer
...
fillplayer
LDX #5
fill2
PLA
STA player1,X
DEX
BPL fill2
RTS
Da sind dann die ersten zwei Bytes die in den Player gehen die Rücksprungadresse und das RTS springt dann dahin, was die ersten beiden Bytes der Playerdaten als Adresse so halt ergeben.
@Dr Irata Dir muß ich das sicher nicht erklären, ist aber vielleicht für Beginner interessant.
Erhard
Jede Info, die zu Hause auf meinem Rechner liegt habe ich unterwegs nicht verfügbar. Jede Info, die im Netz liegt finde ich nicht wieder, wenn ich sie benötige.
Moin, lieben Dank für die Antworten. Klar, wenn ich in einem Unterprogramm bin und mit PHA arbeite, muss ich natürlich vor dem RTS den Stapel wieder korrekt abgebaut haben. LG Peter
Hallo,
Dr. Irata schrieb: multiple Halte-/Abzweigpunkte
hier ist es halt sehr schade, daß es keine X oder Y indexierten JMP-Sprünge gibt.
Vielleicht geht das mit einer Adresstabelle (auf der begehrte Seite 0 schneller)
.org $80
.word addr1-1
.word addr2-1
.word addr3-1
...
.word addrx-1
.org tablejump
; accu wird übergeben und enthält wohin
ASL
TAY
LDA $81,Y
PHA
LDA $80,Y
PHA
RTS
Erhard
Jede Info, die zu Hause auf meinem Rechner liegt habe ich unterwegs nicht verfügbar. Jede Info, die im Netz liegt finde ich nicht wieder, wenn ich sie benötige.
Moin,
ich finde es verwirrend, das man immer 1 von einer Adresse abziehen muss, warum also statt RTS nicht RTI verwenden. Man muss nur etwas extra auf den Stack schieben. Und warum word Adressen, da muss man den eigenen Pointer auch noch verdoppeln.
Nehmt 2 Byte Arrays, einmal mit den niederwertigen Adressen, einmal mit höherwertigen Adressen.
Beispiel für den MAC65/Atasm Assembler
;; 2 Arrays anlegen
low
.byte <address1
.byte <address2
high
.byte >address1
.byte >address2
;; Wenn jetzt im X Register die Position innerhalb des Arrays ankommt
jumplist_x
lda high,x ; high byte der Adresse auf den Stack
pha
lda low,x ; low byte der Adresse
pha
plp ; irgend was auf den Stack
rti ; Rücksprung ohne das man 1 von Adresse abziehen muss
Sieht auf den ersten Blick komisch aus, weil man ja RTI mit Interrupts verbindet, aber das ist völlig egal, es funktioniert.
LarsImNetz schrieb: Beispiel für den MAC65/Atasm Assembler
``` plp ; irgend was auf den Stack
```
Ich würde hier ein PHP empfehlen. 😁
Hallo,
nach dem Durchlesen würde ich eine Mischung aus meinem Vorschlag und dem von Lars verwenden.
Die Idee von Lars mit den getrennten Tabellen für Low- und Highbyte sparen die Multiplikation (ASL) des Inhalts für das X-Register.
Ist etwas mehr Tipparbeit weil man alles quasi 2x schreiben muß. Dadurch wird natürlich der Quellcode länger aber es geht ja darum, es dem 6502 bequem zu machen 🙂
Ich wäre nie auf die Idee gekommen, ein JSR mit einem RTI zu beenden ...
Ich verstehe, daß bei Verwendung von RTI nicht eine um 1 reduzierte Adresse auf dem Stapel liegen muß.
Dafür muß bei RTI ein zusätzlicher Wert auf dem Stapel liegen, weil RTI daraus den Prozessorstatus wiederherstellt.
Dieses PHP kostet aber bei jedem Durchlauf 3 Taktzyklen.
Ergo wird dadurch das Programm länger und langsamer, oder?
Dagegen kostet das Speichern der Adressen um einen um 1 reudzierten Wert nur die Tipparbeit.
Also wäre der (derzeit) kürzeste und schnellste Programmcode doch:
; 2 Arrays anlegen
low
.BYTE <address1-1
.BYTE <address2-1
high
.BYTE >address1-1
.BYTE >address2-1
; Wenn jetzt im X Register die Position innerhalb des Arrays ankommt
jumplist_x
LDA high,x ; high byte der Adresse auf den Stack
PHA
LDA low,x ; low byte der Adresse
PHA
RTS ; Rücksprung ohne das man 1 von Adresse abziehen muss
Erhard
Jede Info, die zu Hause auf meinem Rechner liegt habe ich unterwegs nicht verfügbar. Jede Info, die im Netz liegt finde ich nicht wieder, wenn ich sie benötige.
Ob es mit dem Platz auf dem Stack knapp wird, sollte sich auch durch Beobachtung des Stack Pointer in einem Emulator oder Debugger feststellen lassen. Wenn man nicht Unmengen verschachtelte JSR verwendet, sollte aber genug Platz sein.